<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    const data = [
      {id: '29', pid: '', name: '总裁办'},
      {id: '2c', pid: '', name: '财务部'},
      {id: '2d', pid: '2c', name: '财务核算部'},
      {id: '2f', pid: '2c', name: '薪资管理部'},
      {id: 'd2', pid: '', name: '技术部'},
      {id: 'd3', pid: 'd2', name: 'Java研发部'},
    ]

    const transform = arr => {
      const obj = {}
    
      arr.forEach(item => {
        // 如果 pid 为空字符串, 证明当前项的一级菜单
        // 那么一级菜单就要添加 children 属性
        if (!item.pid) item.children = []
        // 对象使用中括号语法, 是专门针对变量的时候, 
        // 对象取值法
        obj[item.id] = item
        // 由于对象赋值 给的是地址, 所以 obj 对应 key 的对象与数组中每一项对应的对象是一模一样的
      })

      const newArr = []

      arr.forEach(item => {
        const parent = obj[item.pid]
        // 如果 parent 有值, 证明这个一级菜单是有子菜单的, 就把对应的子菜单添加进数组 children 中
        if (parent) {  // 只要进入了这个分支, 证明当前的item 是子元素(二级菜单)
          parent.children?.push(item)
        } else {  // 只要进入了这个分支, 就证明当前的 item 是父元素(一级菜单)
          newArr.push(item)
        }
      })
      return newArr
    }
    transform(data)
    console.log(transform(data));

  </script>
</body>
</html>